using System;
using System.Collections.Generic;
using System.Text;
using TuringMachine.StateAutomat;

namespace TuringMachine.CompilerModule
{
    class Compiler
    {
        private Automat _automat = null;
        private TransactionTable _transactionTable = null;
        private Parser _parser = null;

        public Compiler() 
        {
        }

        public Compiler(ref Automat automat, ref TransactionTable transactionTable)
        {
            _automat = automat;
            _transactionTable = transactionTable;
            _parser = new Parser();
        }

        public void CompileScript(string[] commandsArray)
        {
            State fromState = null;
            char inputChar;
            State toState = null;
            char tapeAction;
            foreach (string command in commandsArray)
            {
                _parser.Parse(command);
                //Get all elements of command
                fromState = _parser.StartState();
                inputChar = _parser.InputChar();
                toState = _parser.NextState();
                tapeAction = _parser.TapeAction();

                //Check if such states already in automat, if not add them
                if (_automat.IsStateInAutomat(fromState))
                {
                    fromState = _automat.GetStateInstance(fromState);
                }
                else
                {
                    _automat.AddState(fromState);
                }

                if (_automat.IsStateInAutomat(toState))
                {
                    toState = _automat.GetStateInstance(toState);
                }
                else
                {
                    _automat.AddState(toState);
                }

                ///TODO: Add deternemistic check
                //Add transaction to table
                if (!_transactionTable.IsFromConfigurationExist(fromState,inputChar))
                {
                    _transactionTable.AddTransaction(fromState, inputChar, toState, tapeAction);
                }

            }

            if (_automat.GetStartState()==null)
            {
                throw new Exception("No start state exist in automat");
            }
            else
            {
                _automat.CurrentState = _automat.GetStartState();
            }
        }
    }
}
